<?php
/////////////////////////////////////////////////////////////////////////////
// 这个文件是 FleaPHP 项目的一部分
//
// Copyright (c) 2005 - 2006 FleaPHP.org (www.fleaphp.org)
//
// 要查看完整的版权信息和许可信息，请查看源代码中附带的 COPYRIGHT 文件，
// 或者访问 http://www.fleaphp.org/ 获得详细信息。
/////////////////////////////////////////////////////////////////////////////

/**
 * 定义 FLEA_View_SmartyHelper 类
 *
 * @copyright Copyright (c) 2005 - 2006 FleaPHP.org (www.fleaphp.org)
 * @author 廖宇雷 dualface@gmail.com
 * @package Core
 * @version $Id: SmartyHelper.php 813 2007-04-09 13:29:50Z dualface $
 */

/**
 * FLEA_View_SmartyHelper 扩展了 Smarty 和 TemplateLite 模版引擎，
 * 提供对 FleaPHP 内置功能的直接支持。
 *
 * @package Core
 * @author 廖宇雷 dualface@gmail.com
 * @version 1.0
 */
class FLEA_View_SmartyHelper
{
    /**
     * 构造函数
     *
     * @param Smarty $tpl
     *
     * @return FLEA_View_SmartyHelper
     */
    function FLEA_View_SmartyHelper(& $tpl) {
        $tpl->register_function('url',          array(& $this, '_pi_func_url'));
        $tpl->register_function('webcontrol',   array(& $this, '_pi_func_webcontrol'));
        $tpl->register_function('_t',           array(& $this, '_pi_func_t'));
        $tpl->register_function('get_app_inf',  array(& $this, '_pi_func_get_app_inf'));
        $tpl->register_function('dump_ajax_js', array(& $this, '_pi_func_dump_ajax_js'));

        $tpl->register_modifier('parse_str',    array(& $this, '_pi_mod_parse_str'));
        $tpl->register_modifier('to_hashmap',   array(& $this, '_pi_mod_to_hashmap'));
        $tpl->register_modifier('col_values',   array(& $this, '_pi_mod_col_values'));
    }

    /**
     * 提供对 FleaPHP url() 函数的支持
     */
    function _pi_func_url($params)
    {
        $controllerName = isset($params['controller']) ?
                $params['controller'] : FLEA::getAppInf('defaultController');
        unset($params['controller']);
        $actionName = isset($params['action']) ?
                $params['action'] : FLEA::getAppInf('defaultAction');
        unset($params['action']);
        $anchor = isset($params['anchor']) ? $params['anchor'] : null;
        unset($params['anchor']);

        $args = array();
        foreach ($params as $key => $value) {
            if (is_array($value)) {
                $args = array_merge($args, $value);
                unset($params[$key]);
            }
        }
        $args = array_merge($args, $params);

        return url($controllerName, $actionName, $args, $anchor);
    }

    /**
     * 提供对 FleaPHP WebControls 的支持
     */
    function _pi_func_webcontrol($params)
    {
        $type = isset($params['type']) ? $params['type'] : 'textbox';
        unset($params['type']);
        $name = isset($params['name']) ? $params['name'] : null;
        unset($params['name']);

        $ui =& FLEA::initWebControls();
        return $ui->control($type, $name, $params, true);
    }

    /**
     * 提供对 FleaPHP _T() 函数的支持
     */
    function _pi_func_t($params)
    {
        return _T($params['key'], isset($params['lang']) ? $params['lang'] : null);
    }

    /**
     * 提供对 FLEA::getAppInf() 方法的支持
     */
    function _pi_func_get_app_inf($params)
    {
        return FLEA::getAppInf($params['key']);
    }

    /**
     * 输出 FLEA_Ajax 生成的脚本
     */
    function _pi_func_dump_ajax_js($params)
    {
        $wrapper = isset($params['wrapper']) ? (bool)$params['wrapper'] : false;
        $ajax =& FLEA::initAjax();
        return $ajax->dumpJs(true, $wrapper);
    }

    /**
     * 将字符串分割为数组
     */
    function _pi_mod_parse_str($string)
    {
        $arr = array();
        parse_str($string, $arr);
        return $arr;
    }

    /**
     * 将二维数组转换为 hashmap
     */
    function _pi_mod_to_hashmap($data, $f_key, $f_value = '')
    {
        $arr = array();
        if (!is_array($data)) { return $arr; }
        if ($f_value != '') {
            foreach ($data as $row) {
                $arr[$row[$f_key]] = $row[$f_value];
            }
        } else {
            foreach ($data as $row) {
                $arr[$row[$f_key]] = $row;
            }
        }
        return $arr;
    }

    /**
     * 获取二维数组中指定列的数据
     */
    function _pi_mod_col_values($data, $f_value)
    {
        $arr = array();
        if (!is_array($data)) { return $arr; }
        foreach ($data as $row) {
            $arr[] = $row[$f_value];
        }
        return $arr;
    }

    /**
     * 按照指定长度截断字符串（汉字算两个位置，支持gbk和utf8编码的中文）
     */
    function _pi_mod_smartTruncate($string, $width = 80, $etc = '...')
    {
        if ($width <= 0) { return ''; }
        if ($this->_pi_mod_smartStrlen($string) > $width) {
            $width -= $this->_pi_mod_smartStrlen($etc);
            return $this->_pi_mod_smartSubstr($string, 0, $width) . $etc;
        } else {
            return $string;
        }
    }

    /**
     * 获得中英文混合字符串的长度（汉字算两个位置，支持gbk和utf8编码的中文）
     */
    function _pi_mod_smartStrlen($string)
    {
        $result = 0;
        $number = smartDetectUTF8($string) ? 3 : 2;
        $bytes = 1;
        for ($i = 0, $max = strlen($string); $i < $max; $i += $bytes) {
            $bytes = ord(substr($string, $i, 1)) > 127 ? $number : 1;
            $result += $bytes > 1 ? 1.0 : 0.5;
        }
        return intval($result);
    }

    /**
     * 取得字符串指定位置和长度的片段（汉字算两个位置，支持gbk和utf8编码的中文）
     */
    function _pi_mod_smartSubstr($string, $offset = 0, $length = null)
    {
        $result = '';
        $number = smartDetectUTF8($string) ? 3 : 2;
        if ($offset < 0) {
            $offset = max(smartStrlen($string) + $offset, 0);
        }

        $bytes = 1;
        for ($i = 0, $max = strlen($string); $i < $max; $i += $bytes) {
            if($offset <= 0) { break; }
            $bytes = ord(substr($string, $i, 1)) > 127 ? $number : 1;
            $offset -= $bytes > 1 ? 1.0 : 0.5;
        }
        if (is_null($length)) {
            $result = substr($string, $i);
        } else {
            for ($j = $i; $j < strlen($string); $j += $bytes) {
                if ($length <= 0) { break; }
                if (($bytes = ord(substr($string, $j, 1)) > 127 ? $number : 1) > 1) {
                    if($length < 1.0) { break; }
                    $result .= substr($string, $j, $bytes);
                    $length -= 1.0;
                } else {
                    $result .= substr($string, $j, 1);
                    $length -= 0.5;
                }
            }
        }

        return $result;
    }

    /**
     * 检查是否是 utf8 编码
     *
     * @param unknown_type $string
     * @return unknown
     */
    function smartDetectUTF8($string)
    {
        static $result = array();

        if(! array_key_exists($key = md5($string), $result))
        {
            $utf8 = "
                /^(?:
                    [\x09\x0A\x0D\x20-\x7E]             # ASCII
                    | [\xC2-\xDF][\x80-\xBF]            # non-overlong 2-byte
                    | \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
                    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
                    | \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
                    | \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
                    | [\xF1-\xF3][\x80-\xBF]{3}         # planes 4-15
                    | \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
                )+$/xs
            ";
            $result[$key] = preg_match(trim($utf8), $string);
        }

        return $result[$key];
    }
}
